#include <cahousek/CAHouseKE.h>
#include <public/humsat_unitime.h>
#include <iostream>

using namespace std;
// ***********************************************************************

// class EDROOMTopContext

// ***********************************************************************



	// CONSTRUCTORES***********************************************

CAHouseK::EDROOMTopContext::EDROOMTopContext (CAHouseK &act, TEDROOMUInt32 & EDROOMpVarVNextHouseKUniTimeSecns, TEDROOMByte & EDROOMpVarVStatus, CEDROOMPOOLTEDROOMByte & EDROOMpPoolTEDROOMByte ):

	EDROOMcomponent(act)
	,Msg(EDROOMcomponent.Msg)
	,MsgBack(EDROOMcomponent.MsgBack)
	,PlannerHousek(EDROOMcomponent.PlannerHousek)
	,Timer(EDROOMcomponent.Timer)
	, CEmergencyMask ( 0x80 )
	, CSGIOnMask ( 0x02 )
	, CSSIOnMask ( 0x01 )
	, VNextHouseKUniTimeSecns ( EDROOMpVarVNextHouseKUniTimeSecns )
	, VStatus ( EDROOMpVarVStatus )
	, EDROOMPoolTEDROOMByte ( EDROOMpPoolTEDROOMByte )
 {

}

CAHouseK::EDROOMTopContext::EDROOMTopContext ( EDROOMTopContext &contex ):

	EDROOMcomponent(contex.EDROOMcomponent),
	Msg(contex.Msg),
	MsgBack(contex.MsgBack)
	,PlannerHousek(contex.PlannerHousek)
	,Timer(contex.Timer)
	, CEmergencyMask ( 0x80 )
	, CSGIOnMask ( 0x02 )
	, CSSIOnMask ( 0x01 )
	, VNextHouseKUniTimeSecns ( contex.VNextHouseKUniTimeSecns )
	, VStatus ( contex.VStatus )
	, EDROOMPoolTEDROOMByte ( contex.EDROOMPoolTEDROOMByte )
 {

}

	// EDROOMSearchContextTrans********************************************

bool CAHouseK::EDROOMTopContext::EDROOMSearchContextTrans(TEDROOMTransId &edroomCurrentTrans){

	bool edroomValidMsg=false; 

	 switch(Msg->signal){

		 case (EDROOMSignalTimeout): 

				if ( *Msg->GetPInterface() == Timer) {

					edroomCurrentTrans.localId= DoHouseKeeping;
					edroomCurrentTrans.distanceToContext = 0;
					edroomValidMsg=true;
				 }

			 break;

		 case ( EDROOMSignalDestroy ): 

			 edroomValidMsg=true;
			 edroomCurrentTrans.distanceToContext = 0 ;
			 edroomCurrentTrans.localId = -1 ;
			 break;

	}

	return(edroomValidMsg);

}

	// Funciones Definidas por el usuario  ****************************

void	CAHouseK::EDROOMTopContext::FDoHouseK()

{
 
 
	TEDROOMByte * ap_TEDROOMByte = EDROOMPoolTEDROOMByte.AllocData();
	
		// Complete Data 
 
	//Una funci�n random para activar el flag de emergencia....
 
	//VStatus|=CEmergencyMask;
 
 
	*ap_TEDROOMByte=VStatus;
	
 
		// send new Msg
	
	PlannerHousek.send(SHouseKStatus, EDROOMprioNormal, ap_TEDROOMByte, &EDROOMPoolTEDROOMByte);
 
 
   VNextHouseKUniTimeSecns+=10;
 
	Pr_Time	time (Pr_Time::secns, VNextHouseKUniTimeSecns);
	 
	Timer.InformAt( time, EDROOMprioNormal );
 
 
}



void	CAHouseK::EDROOMTopContext::FEndSGIComm()

{
 
  VStatus&=~CSGIOnMask;
 
  cout<<"He llegado yujuu!: FEndSGIComm "<<endl;
 
	TEDROOMByte * ap_TEDROOMByte = EDROOMPoolTEDROOMByte.AllocData();
	
		// Complete Data 
	
	ap_TEDROOMByte;
	
		// reply 
	
	Msg->reply(SSSIStarted, ap_TEDROOMByte, &EDROOMPoolTEDROOMByte);
 
}



void	CAHouseK::EDROOMTopContext::FEndSSIComm()

{
 
 VStatus&=~CSSIOnMask;
 
  cout<<"He llegado: FEndSSIComm "<<endl;
 
	TEDROOMByte * ap_TEDROOMByte = EDROOMPoolTEDROOMByte.AllocData();
	
		// Complete Data 
	
	ap_TEDROOMByte;
	
		// reply 
	
	Msg->reply(SSSIStarted, ap_TEDROOMByte, &EDROOMPoolTEDROOMByte);
 
}



void	CAHouseK::EDROOMTopContext::FInit()

{
 
	VNextHouseKUniTimeSecns=CUniTime::GetCurrentUniTimeSeconds()+10;
 
	Pr_Time	time (Pr_Time::secns, VNextHouseKUniTimeSecns);
	 
	Timer.InformAt( time, EDROOMprioNormal );
  	
 
}
		



void	CAHouseK::EDROOMTopContext::FStartSGIComm()

{
  VStatus|=CSGIOnMask;
 
   cout<<"He llegado FStartSGIComm"<<endl;
 
	TEDROOMByte * ap_TEDROOMByte = EDROOMPoolTEDROOMByte.AllocData();
	
		// Complete Data 
	
	*ap_TEDROOMByte=VStatus;
	
		// reply 
	
	Msg->reply(SSSIStarted, ap_TEDROOMByte, &EDROOMPoolTEDROOMByte);
 
 
 
 
}



void	CAHouseK::EDROOMTopContext::FStartSSIComm()

{
 
  VStatus|=CSSIOnMask;
 
   cout<<" He llegado FStartSSIComm"<<endl;
 
	TEDROOMByte * ap_TEDROOMByte = EDROOMPoolTEDROOMByte.AllocData();
	
		// Complete Data 
	
	*ap_TEDROOMByte=VStatus;
	
		// reply 
	
	Msg->reply(SSSIStarted, ap_TEDROOMByte, &EDROOMPoolTEDROOMByte);
 
  
 
}



void	CAHouseK::EDROOMTopContext::FToEmergency()

{
 
	VStatus=CEmergencyMask;
 
}



void	CAHouseK::EDROOMTopContext::FToStandBy()

{
 VStatus=0x00; 
  
}



	//*****Pools

	//CEDROOMPOOLTEDROOMByte

CAHouseK::EDROOMTopContext::CEDROOMPOOLTEDROOMByte::CEDROOMPOOLTEDROOMByte(unsigned int elemCount, TEDROOMByte* pMem, TEDROOMBool * pMemMarks):CEDROOMProtectedMemoryPool(elemCount, pMem, pMemMarks, sizeof (TEDROOMByte)){;}

TEDROOMByte *	CAHouseK::EDROOMTopContext::CEDROOMPOOLTEDROOMByte::AllocData(){
	return(TEDROOMByte*)CEDROOMProtectedMemoryPool::AllocData();
}



// ***********************************************************************

// class EDROOMTopState

// ***********************************************************************



	// CONSTRUCTOR*************************************************

CAHouseK::EDROOMTopState::EDROOMTopState (CAHouseK &act, CEDROOMMemory *pEDROOMMemory  ):
	  EDROOMTopContext( act , VNextHouseKUniTimeSecns, VStatus,EDROOMPoolTEDROOMByte )
	, VNextHouseKUniTimeSecns (   )
	, VStatus (   )
	, EDROOMPoolTEDROOMByte ( 10, pEDROOMMemory->poolTEDROOMByte, pEDROOMMemory->poolMarkTEDROOMByte)
{

}

	// EDROOMBehaviour**********************************************

void CAHouseK::EDROOMTopState::EDROOMBehaviour(){

	TEDROOMTransId edroomCurrentTrans;

	edroomCurrentTrans = EDROOMIllegada();

	do{

		switch(edroomCurrentTrans.localId){

			case(Init):
				FInit();
				edroomNextState = Ready;
				break;
			case(DoHouseKeeping):
				FDoHouseK();
				edroomNextState = edroomCurrentState;
				edroomCurrentTrans.localId=EDROOMMEMORIA;
				break;
			case(StartSSIComm):
				FStartSSIComm();
				edroomNextState = Ready;
				break;
			case(EndSSIComm):
				FEndSSIComm();
				edroomNextState = Ready;
				break;
			case(StartSGIComm):
				FStartSGIComm();
				edroomNextState = Ready;
				break;
			case(EndSGIComm):
				FEndSGIComm();
				edroomNextState = Ready;
				break;
			case(ToEmergency):
				FToEmergency();
				edroomNextState = Emergency;
				break;
			case(ToStandBy):
				FToStandBy();
				edroomNextState = Ready;
				break;
		}

		EDROOMcomponent.EDROOMTraceStateEntry();

		EDROOMcomponent.EDROOMTraceStateEntry();

		switch(edroomNextState){

			case(I):
				edroomCurrentTrans=EDROOMIllegada();
				break;

			case(Ready):
				edroomCurrentTrans=EDROOMReadyllegada();
				break;

			case(Emergency):
				edroomCurrentTrans=EDROOMEmergencyllegada();
				break;

		}

		EDROOMcomponent.EDROOMTraceStateExit();

		edroomCurrentState=edroomNextState;

	}while(Msg->signal != EDROOMSignalDestroy);

}



	// Inicio**********************************************

void CAHouseK::EDROOMTopState::EDROOMInicio(){

edroomCurrentState=I;

}



//	 ***********************************************************************

//	 llegada SubEstado I

//	 ***********************************************************************



TEDROOMTransId CAHouseK::EDROOMTopState::EDROOMIllegada(){

	TEDROOMTransId edroomCurrentTrans;

	edroomCurrentTrans.localId = Init;
	edroomCurrentTrans.distanceToContext = 0;
	EDROOMcomponent.EDROOMTraceTrans(edroomCurrentTrans, 0);

	return(edroomCurrentTrans);

}



	// ***********************************************************************

	// llegada SubEstado Hoja Ready

	// ***********************************************************************



TEDROOMTransId CAHouseK::EDROOMTopState::EDROOMReadyllegada(){

	TEDROOMTransId edroomCurrentTrans;

	int edroomValidMsg=false;

	do{

		EDROOMNuevoMens ();

		switch(Msg->signal){

			case (SStartSSIComm): 

				 if ( *Msg->GetPInterface() == PlannerHousek) {

					edroomCurrentTrans.localId= StartSSIComm;
					edroomCurrentTrans.distanceToContext = 0;
					edroomValidMsg=true;
				 }

				break;

			case (SEndSSIComm): 

				 if ( *Msg->GetPInterface() == PlannerHousek) {

					edroomCurrentTrans.localId= EndSSIComm;
					edroomCurrentTrans.distanceToContext = 0;
					edroomValidMsg=true;
				 }

				break;

			case (SStartSGIComm): 

				 if ( *Msg->GetPInterface() == PlannerHousek) {

					edroomCurrentTrans.localId= StartSGIComm;
					edroomCurrentTrans.distanceToContext = 0;
					edroomValidMsg=true;
				 }

				break;

			case (SEndSGIComm): 

				 if ( *Msg->GetPInterface() == PlannerHousek) {

					edroomCurrentTrans.localId= EndSGIComm;
					edroomCurrentTrans.distanceToContext = 0;
					edroomValidMsg=true;
				 }

				break;

			case (SToEmergency): 

				 if ( *Msg->GetPInterface() == PlannerHousek) {

					edroomCurrentTrans.localId= ToEmergency;
					edroomCurrentTrans.distanceToContext = 0;
					edroomValidMsg=true;
				 }

				break;

		};

		if (!edroomValidMsg) edroomValidMsg = EDROOMSearchContextTrans(edroomCurrentTrans);

	} while (!edroomValidMsg);

	EDROOMcomponent.EDROOMTraceTrans(edroomCurrentTrans, Msg->signal);

	return(edroomCurrentTrans);

}



	// ***********************************************************************

	// llegada SubEstado Hoja Emergency

	// ***********************************************************************



TEDROOMTransId CAHouseK::EDROOMTopState::EDROOMEmergencyllegada(){

	TEDROOMTransId edroomCurrentTrans;

	int edroomValidMsg=false;

	do{

		EDROOMNuevoMens ();

		switch(Msg->signal){

			case (SToStandBy): 

				 if ( *Msg->GetPInterface() == PlannerHousek) {

					edroomCurrentTrans.localId= ToStandBy;
					edroomCurrentTrans.distanceToContext = 0;
					edroomValidMsg=true;
				 }

				break;

		};

		if (!edroomValidMsg) edroomValidMsg = EDROOMSearchContextTrans(edroomCurrentTrans);

	} while (!edroomValidMsg);

	EDROOMcomponent.EDROOMTraceTrans(edroomCurrentTrans, Msg->signal);

	return(edroomCurrentTrans);

}



